原始题目:剑指 Offer 42. 连续子数组的最大和 (opens new window)
解题思路:
假设 表示数组 在 区间的最大和
- 如果 ,那么在计算 时,就需要把 抛弃。因为 只会带来负贡献,即 ,因此 $sum(i) = nums[i] $时最好的选择。
- 如果 ,那么在计算 时,存在 的情况,因此 $ sum(i) = sum(i-1) + nums[i]$ 是最好的选择。
代码:
public int maxSubArray(int[] nums) {
if (nums == null || nums.length == 0) {
return 0;
}
int ans = Integer.MIN_VALUE;
int curSum = 0;
for (int i = 0; i < nums.length; i++) {
if (curSum < 0) {
// 如果 curSum 已经小于0了,那么此时 curSum += nums[i] 的话,
// 对 nums[i] 回造成负贡献,因此摒弃之前的子数组和,从 nums[i] 开始重新计算
curSum = nums[i];
} else {
curSum += nums[i];
}
ans = Math.max(curSum, ans);
}
return ans;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
复杂度分析
- 时间复杂度: 为数组的元素个数。
- 空间复杂度:使用常数大小的额外空间。